<template>
  <div class="page-container">
    <!-- 页面标题 -->
    <div class="flex justify-between items-center mb-6">
      <div>
        <h1 class="page-title">角色管理</h1>
        <div class="breadcrumb-container">
          <router-link to="/" class="link link-hover">首页</router-link>
          <span class="mx-2">/</span>
          <span>系统管理</span>
          <span class="mx-2">/</span>
          <span>角色管理</span>
        </div>
      </div>
      <div class="btn-group">
        <button class="btn btn-primary gap-2" @click="handleNewRole">
          <svg xmlns="http://www.w3.org/2000/svg" class="h-5 w-5" viewBox="0 0 20 20" fill="currentColor">
            <path fill-rule="evenodd" d="M10 18a8 8 0 100-16 8 8 0 000 16zm1-11a1 1 0 10-2 0v2H7a1 1 0 100 2h2v2a1 1 0 102 0v-2h2a1 1 0 100-2h-2V7z" clip-rule="evenodd" />
          </svg>
          新增角色
        </button>
      </div>
    </div>

    <!-- 搜索栏 -->
    <div class="card bg-base-100 shadow-lg mb-6">
      <div class="card-body">
        <div class="flex gap-4">
          <div class="form-control flex-1">
            <label class="label">
              <span class="label-text">关键词</span>
            </label>
            <input
              v-model="searchForm.keyword"
              type="text"
              placeholder="请输入角色名称或描述"
              class="input input-bordered"
            />
          </div>
          <div class="flex items-end">
            <button class="btn btn-ghost" @click="resetSearch">重置</button>
            <button class="btn btn-primary ml-2" @click="handleSearch">搜索</button>
          </div>
        </div>
      </div>
    </div>

    <!-- 数据表格 -->
    <div class="card bg-base-100 shadow-lg">
      <div class="card-body">
        <div class="overflow-x-auto">
          <table class="table">
            <thead>
              <tr>
                <th>ID</th>
                <th>角色名称</th>
                <th>描述</th>
                <th>权限数量</th>
                <th>创建时间</th>
                <th>更新时间</th>
                <th>操作</th>
              </tr>
            </thead>
            <tbody>
              <tr v-for="role in roles" :key="role.id">
                <td class="font-mono text-sm">{{ role.id }}</td>
                <td>{{ role.name }}</td>
                <td>{{ role.description }}</td>
                <td>{{ role.permissions.length }}</td>
                <td>{{ formatDate(role.createdAt) }}</td>
                <td>{{ formatDate(role.updatedAt) }}</td>
                <td>
                  <div class="btn-group">
                    <button class="btn btn-ghost btn-sm" @click="handleEdit(role)">
                      <svg xmlns="http://www.w3.org/2000/svg" class="h-4 w-4" viewBox="0 0 20 20" fill="currentColor">
                        <path d="M13.586 3.586a2 2 0 112.828 2.828l-.793.793-2.828-2.828.793-.793zM11.379 5.793L3 14.172V17h2.828l8.38-8.379-2.83-2.828z" />
                      </svg>
                    </button>
                    <button class="btn btn-ghost btn-sm" @click="handlePermissions(role)">
                      <svg xmlns="http://www.w3.org/2000/svg" class="h-4 w-4" viewBox="0 0 20 20" fill="currentColor">
                        <path fill-rule="evenodd" d="M2.166 4.999A11.954 11.954 0 0010 1.944 11.954 11.954 0 0017.834 5c.11.65.166 1.32.166 2.001 0 5.225-3.34 9.67-8 11.317C5.34 16.67 2 12.225 2 7c0-.682.057-1.35.166-2.001zm11.541 3.708a1 1 0 00-1.414-1.414L9 10.586 7.707 9.293a1 1 0 00-1.414 1.414l2 2a1 1 0 001.414 0l4-4z" clip-rule="evenodd" />
                      </svg>
                    </button>
                    <button class="btn btn-ghost btn-sm" @click="handleDelete(role)">
                      <svg xmlns="http://www.w3.org/2000/svg" class="h-4 w-4" viewBox="0 0 20 20" fill="currentColor">
                        <path fill-rule="evenodd" d="M9 2a1 1 0 00-.894.553L7.382 4H4a1 1 0 000 2v10a2 2 0 002 2h8a2 2 0 002-2V6a1 1 0 100-2h-3.382l-.724-1.447A1 1 0 0011 2H9zM7 8a1 1 0 012 0v6a1 1 0 11-2 0V8zm5-1a1 1 0 00-1 1v6a1 1 0 102 0V8a1 1 0 00-1-1z" clip-rule="evenodd" />
                      </svg>
                    </button>
                  </div>
                </td>
              </tr>
            </tbody>
          </table>
        </div>

        <!-- 分页 -->
        <div class="flex justify-between items-center mt-4">
          <div class="text-sm text-base-content/60">
            共 {{ total }} 条记录
          </div>
          <div class="join">
            <button class="join-item btn btn-sm" :disabled="currentPage === 1" @click="handlePageChange(currentPage - 1)">
              <svg xmlns="http://www.w3.org/2000/svg" class="h-4 w-4" viewBox="0 0 20 20" fill="currentColor">
                <path fill-rule="evenodd" d="M12.707 5.293a1 1 0 010 1.414L9.414 10l3.293 3.293a1 1 0 01-1.414 1.414l-4-4a1 1 0 010-1.414l4-4a1 1 0 011.414 0z" clip-rule="evenodd" />
              </svg>
            </button>
            <button class="join-item btn btn-sm">{{ currentPage }} / {{ totalPages }}</button>
            <button class="join-item btn btn-sm" :disabled="currentPage === totalPages" @click="handlePageChange(currentPage + 1)">
              <svg xmlns="http://www.w3.org/2000/svg" class="h-4 w-4" viewBox="0 0 20 20" fill="currentColor">
                <path fill-rule="evenodd" d="M7.293 14.707a1 1 0 010-1.414L10.586 10 7.293 6.707a1 1 0 011.414-1.414l4 4a1 1 0 010 1.414l-4 4a1 1 0 01-1.414 0z" clip-rule="evenodd" />
              </svg>
            </button>
          </div>
        </div>
      </div>
    </div>

    <!-- 编辑对话框 -->
    <dialog ref="editDialog" class="modal">
      <div class="modal-box">
        <h3 class="font-bold text-lg mb-4">{{ isEdit ? '编辑角色' : '新增角色' }}</h3>
        <form @submit.prevent="handleSubmit" class="space-y-4">
          <div class="form-control">
            <label class="label">
              <span class="label-text">角色名称</span>
            </label>
            <input
              type="text"
              v-model="form.name"
              placeholder="请输入角色名称"
              class="input input-bordered"
              :class="{ 'input-error': errors.name }"
            />
            <label class="label" v-if="errors.name">
              <span class="label-text-alt text-error">{{ errors.name }}</span>
            </label>
          </div>
          <div class="form-control">
            <label class="label">
              <span class="label-text">描述</span>
            </label>
            <textarea
              v-model="form.description"
              placeholder="请输入角色描述"
              class="textarea textarea-bordered"
              :class="{ 'textarea-error': errors.description }"
            ></textarea>
            <label class="label" v-if="errors.description">
              <span class="label-text-alt text-error">{{ errors.description }}</span>
            </label>
          </div>
        </form>
        <div class="modal-action">
          <button class="btn btn-ghost" @click="closeDialog">取消</button>
          <button
            class="btn btn-primary"
            :class="{ loading: isSubmitting }"
            @click="handleSubmit"
          >
            确定
          </button>
        </div>
      </div>
      <form method="dialog" class="modal-backdrop">
        <button>关闭</button>
      </form>
    </dialog>

    <!-- 权限对话框 -->
    <dialog ref="permissionsDialog" class="modal">
      <div class="modal-box max-w-3xl">
        <h3 class="font-bold text-lg mb-4">权限设置 - {{ selectedRole?.name }}</h3>
        <div class="space-y-4">
          <div v-for="module in permissions" :key="module.name" class="card bg-base-200">
            <div class="card-body">
              <div class="flex items-center gap-4">
                <label class="cursor-pointer label">
                  <input
                    type="checkbox"
                    :checked="isModuleSelected(module)"
                    @change="toggleModule(module)"
                    class="checkbox"
                  />
                  <span class="label-text ml-2 font-bold">{{ module.name }}</span>
                </label>
              </div>
              <div class="grid grid-cols-3 gap-4 mt-2">
                <label
                  v-for="permission in module.children"
                  :key="permission.code"
                  class="cursor-pointer label"
                >
                  <input
                    type="checkbox"
                    v-model="selectedPermissions"
                    :value="permission.code"
                    class="checkbox checkbox-sm"
                  />
                  <span class="label-text ml-2">{{ permission.name }}</span>
                </label>
              </div>
            </div>
          </div>
        </div>
        <div class="modal-action">
          <button class="btn btn-ghost" @click="closePermissionsDialog">取消</button>
          <button
            class="btn btn-primary"
            :class="{ loading: isUpdatingPermissions }"
            @click="handleUpdatePermissions"
          >
            确定
          </button>
        </div>
      </div>
      <form method="dialog" class="modal-backdrop">
        <button>关闭</button>
      </form>
    </dialog>

    <!-- 删除确认对话框 -->
    <dialog ref="deleteDialog" class="modal">
      <div class="modal-box">
        <h3 class="font-bold text-lg">确认删除</h3>
        <p class="py-4">确定要删除该角色吗？此操作不可撤销。</p>
        <div class="modal-action">
          <button class="btn btn-ghost" @click="closeDeleteDialog">取消</button>
          <button
            class="btn btn-error"
            :class="{ loading: isDeleting }"
            @click="confirmDelete"
          >
            删除
          </button>
        </div>
      </div>
      <form method="dialog" class="modal-backdrop">
        <button>关闭</button>
      </form>
    </dialog>
  </div>
</template>

<script setup lang="ts">
import { ref, reactive, onMounted } from 'vue'
import { formatDate } from '@/utils/date'
import { SystemService, type Role, type Permission } from '@/api/services'
import { useLoadingStore } from '@/stores/loading'
import { useToast } from '@/composables/useToast'

const loadingStore = useLoadingStore()
const toast = useToast()

// 状态
const roles = ref<Role[]>([])
const permissions = ref<Permission[]>([])
const currentPage = ref(1)
const total = ref(0)
const totalPages = ref(1)
const pageSize = 10

// 搜索表单
interface SearchForm {
  keyword: string
}

const searchForm = reactive<SearchForm>({
  keyword: '',
})

// 编辑表单
interface Form {
  name: string
  description: string
  permissions: string[]
}

interface FormErrors {
  name: string
  description: string
}

const form = reactive<Form>({
  name: '',
  description: '',
  permissions: [],
})

const errors = reactive<FormErrors>({
  name: '',
  description: '',
})

// 对话框状态
const editDialog = ref<HTMLDialogElement | null>(null)
const permissionsDialog = ref<HTMLDialogElement | null>(null)
const deleteDialog = ref<HTMLDialogElement | null>(null)
const isEdit = ref(false)
const isSubmitting = ref(false)
const isDeleting = ref(false)
const isUpdatingPermissions = ref(false)
const selectedRole = ref<Role | null>(null)
const selectedPermissions = ref<string[]>([])

// 方法
const loadRoles = async () => {
  try {
    loadingStore.show()
    const { items, total: totalCount } = await SystemService.getRoles({
      page: currentPage.value,
      pageSize,
      ...searchForm,
    })
    roles.value = items
    total.value = totalCount
    totalPages.value = Math.ceil(totalCount / pageSize)
  } catch (error: any) {
    toast.error(error.message)
  } finally {
    loadingStore.hide()
  }
}

const loadPermissions = async () => {
  try {
    loadingStore.show()
    permissions.value = await SystemService.getPermissions()
  } catch (error: any) {
    toast.error(error.message)
  } finally {
    loadingStore.hide()
  }
}

const handleNewRole = () => {
  isEdit.value = false
  form.name = ''
  form.description = ''
  form.permissions = []
  Object.keys(errors).forEach(key => {
    errors[key as keyof FormErrors] = ''
  })
  editDialog.value?.showModal()
}

const handleEdit = (role: Role) => {
  isEdit.value = true
  selectedRole.value = role
  form.name = role.name
  form.description = role.description
  form.permissions = [...role.permissions]
  Object.keys(errors).forEach(key => {
    errors[key as keyof FormErrors] = ''
  })
  editDialog.value?.showModal()
}

const handlePermissions = async (role: Role) => {
  selectedRole.value = role
  selectedPermissions.value = [...role.permissions]
  if (permissions.value.length === 0) {
    await loadPermissions()
  }
  permissionsDialog.value?.showModal()
}

const handleDelete = (role: Role) => {
  selectedRole.value = role
  deleteDialog.value?.showModal()
}

const validateForm = () => {
  let isValid = true
  if (!form.name) {
    errors.name = '请输入角色名称'
    isValid = false
  }
  if (!form.description) {
    errors.description = '请输入角色描述'
    isValid = false
  }
  return isValid
}

const handleSubmit = async () => {
  if (!validateForm()) {
    return
  }

  try {
    isSubmitting.value = true
    if (isEdit.value && selectedRole.value) {
      await SystemService.updateRole(selectedRole.value.id, form)
      toast.success('修改成功')
    } else {
      await SystemService.createRole(form)
      toast.success('新增成功')
    }
    closeDialog()
    loadRoles()
  } catch (error: any) {
    toast.error(error.message)
  } finally {
    isSubmitting.value = false
  }
}

const handleUpdatePermissions = async () => {
  if (!selectedRole.value) return

  try {
    isUpdatingPermissions.value = true
    await SystemService.updatePermissions({
      roleId: selectedRole.value.id,
      permissions: selectedPermissions.value,
    })
    toast.success('权限更新成功')
    closePermissionsDialog()
    loadRoles()
  } catch (error: any) {
    toast.error(error.message)
  } finally {
    isUpdatingPermissions.value = false
  }
}

const confirmDelete = async () => {
  if (!selectedRole.value) return

  try {
    isDeleting.value = true
    await SystemService.deleteRole(selectedRole.value.id)
    toast.success('删除成功')
    closeDeleteDialog()
    loadRoles()
  } catch (error: any) {
    toast.error(error.message)
  } finally {
    isDeleting.value = false
  }
}

const isModuleSelected = (module: Permission) => {
  return module.children?.every(permission => selectedPermissions.value.includes(permission.code))
}

const toggleModule = (module: Permission) => {
  const isSelected = isModuleSelected(module)
  module.children?.forEach(permission => {
    const index = selectedPermissions.value.indexOf(permission.code)
    if (isSelected && index > -1) {
      selectedPermissions.value.splice(index, 1)
    } else if (!isSelected && index === -1) {
      selectedPermissions.value.push(permission.code)
    }
  })
}

const handleSearch = () => {
  currentPage.value = 1
  loadRoles()
}

const resetSearch = () => {
  searchForm.keyword = ''
  handleSearch()
}

const handlePageChange = (page: number) => {
  currentPage.value = page
  loadRoles()
}

const closeDialog = () => {
  editDialog.value?.close()
}

const closePermissionsDialog = () => {
  permissionsDialog.value?.close()
}

const closeDeleteDialog = () => {
  deleteDialog.value?.close()
}

// 生命周期
onMounted(() => {
  loadRoles()
})
</script>
